package com.sls.game.service.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.PropertiesUtil;
import com.sls.core.util.ServerDateAndTime;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.common.DeductionRefund;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.maxshu.MaxshuAccountDAO;
import com.sls.game.dao.maxshu.MaxshuAsDAO;
import com.sls.game.dao.maxshu.MaxshuDAO;
import com.sls.game.dao.maxshu.MaxshuRechargeDAO;
import com.sls.game.page.Pagination;
import com.sls.game.parser.ParseMaxshuRespInfo;
import com.sls.game.parser.sls.OrderStatusSendParse;
import com.sls.game.pojo.DeductionRefundInfo;
import com.sls.game.pojo.DownstreamUserInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.pojo.maxshu.MaxshuAccountType;
import com.sls.game.pojo.maxshu.MaxshuAreaServer;
import com.sls.game.pojo.maxshu.MaxshuProduct;
import com.sls.game.pojo.maxshu.MaxshuRechargeType;
import com.sls.game.pojo.maxshu.MaxshuRespInfo;
import com.sls.game.service.BaseService;
import com.sls.game.service.MaxshuSupService;

@Service("maxshuEsalesService")
public class MaxshuSupServiceImpl implements MaxshuSupService {

	private static String filename = "maxshu.properties";
	private static Logger log = Logger.getLogger(MaxshuSupServiceImpl.class);
	@Resource(name = "maxshuDAO")
	private MaxshuDAO maxshuDAO;
	@Resource(name = "maxshuAccountDAO")
	private MaxshuAccountDAO maxshuAccountDAO;
	@Resource(name = "maxshuRechargeDAO")
	private MaxshuRechargeDAO maxshuRechargeDAO;
	@Resource(name = "maxshuAsDAO")
	private MaxshuAsDAO maxshuAsDAO;
	@Resource(name = "goodsOrderDAO")
	private GoodsOrderDAO goodsOrderDAO;
	@Resource(name = "downstreamUserDAO")
	private DownstreamUserDAO downstreamUserDAO;
	@Resource(name = "baseServiceImp")
	private BaseService baseService;
	
	private Gson gson;

	
	public MaxshuSupServiceImpl() {
		gson = CommonUtil.gson();
	}
	/**
	 * 获取工号信息
	 * */
	@Override
	public MaxshuRespInfo queryMerchantInfo(Head head) {
		MaxshuRespInfo respInfo = null;
		String address = PropertiesUtil.getValue(
				"maxshu.interface.query.merchant.address", filename);
		String md5key = PropertiesUtil.getValue("maxshu.md5.key", filename);
		String merchantId = PropertiesUtil.getValue("maxshu.merchant.id",
				filename);
		HttpClient httpClient = new HttpClient();
		String data = merchantId + md5key;
		String sign = UtilMD5Encryption.createMD5Encryption(data);
		Map<String, String> map = new HashMap<String, String>();
		map.put("MerchantID", merchantId);
		map.put("Sign", sign);
		try {
			log.info("请求ID：" + head.getRequestId() + "--发送到数网查询商家信息的请求参数："
					+ address + map);
			String xmlStr = httpClient.doPost(address, map);
			log.info("请求ID：" + head.getRequestId() + "--数网返回给易卡汇的请求结果："
					+ xmlStr);
			if (StringUtils.isNotEmpty(xmlStr)) {
				respInfo = ParseMaxshuRespInfo.getBalanceInfo(xmlStr);
			}
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "--数网查询商家信息请求异常！", e);
		}
		return respInfo;
	}
	/**
	 * 同步上游所有产品信息
	 * */
	@Override
	public void saveAllProductDetailInfo(Head head) {
		final String address = PropertiesUtil.getValue(
				"maxshu.interface.query.product.detail.address", filename);
		final Head head2 = head;
		final List<MaxshuProduct> list = this.getAllProduct(head);
		if (list != null && !list.isEmpty()) {
			new Thread(new Runnable() {
				HttpClient httpClient = new HttpClient();

				@Override
				public void run() {
					for (MaxshuProduct wp : list) {
						String productId = wp.getProductId();
						maxshuAsDAO.deleteByProductId(productId);
						maxshuRechargeDAO.deleteByProductId(productId);
						maxshuAccountDAO.deleteByProductId(productId);
						try {
							// 对返回的字符串数据进行解析
							Map<String, String> map = new HashMap<String, String>();
							map.put("ProductID", productId);
							log.info("请求ID：" + head2.getRequestId()
									+ "--发送到数网同步详细产品的请求参数：" + address + map);
							String xmlStr = httpClient.doPost(address, map);
							log.info("请求ID：" + head2.getRequestId()
									+ "--数网返回给手拉手的请求结果：" + xmlStr);
							if (StringUtils.isNotEmpty(xmlStr)) {
								
								wp.setIsAudit("0");
								MaxshuProduct maxshuproduct = maxshuDAO.queryByProId(wp.getProductId());
								if(maxshuproduct == null){
									wp.setId(UUID.randomUUID().toString());
									maxshuDAO.insertProduct(wp);
								}else{
									maxshuDAO.update(wp);
								}
								

								ParseMaxshuRespInfo.saveAssistInfo(xmlStr,
										maxshuAccountDAO, maxshuRechargeDAO,
										maxshuAsDAO);
							}
						} catch (Exception e) {
							log.error(
									"请求ID：" + head2.getRequestId() + "--产品编号："
											+ productId + "--数网同步详细产品请求异常！", e);
							continue;
						}
					}
				}
			}).start();
		} else {
			throw new ServerDisponseException("PRODUCT_LIST_EMPTY", "请先导入产品数据");
		}
	}
	/**
	 * 迭代商品信息
	 * */
	private List<MaxshuProduct> getAllProduct(Head head) {
		List<MaxshuProduct> list = null;
		String address = PropertiesUtil.getValue(
				"maxshu.interface.query.all.product.address", filename);
		HttpClient httpClient = new HttpClient();
		try {
			// 对返回的字符串数据进行解析
			Map<String, String> map = new HashMap<String, String>();
			log.info("请求ID：" + head.getRequestId() + "--发送到数网同步所有产品的请求参数："
					+ address);
			String xmlStr = httpClient.doPost(address, map);
			log.info("请求ID：" + head.getRequestId() + "--数网返回给手拉手的请求结果："
					+ xmlStr);
			if (StringUtils.isNotEmpty(xmlStr)) {
				list = ParseMaxshuRespInfo.getAllProduct(xmlStr);
			}
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "--数网同步产品请求异常！", e);
			throw new ServerDisponseException(
					ExceptionCodeDes.HTTP_URL_FAILED.getCode(),
					ExceptionCodeDes.HTTP_URL_FAILED.getDescription());
		}

		// list = this.maxshuDAO.queryAllWoInfo(new MaxshuProduct());
		return list;
	}
	/**
	 * 订单查询
	 * */
	@Override
	public MaxshuRespInfo queryOrder(String body, Head head) {
		MaxshuRespInfo reqInfo = gson.fromJson(body, MaxshuRespInfo.class);
		if (reqInfo == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.PARSE_REQUEST_ERROR.getCode(),
					ExceptionCodeDes.PARSE_REQUEST_ERROR.getDescription());
		}
		String orderId = reqInfo.getOrderId();
		if (StringUtils.isEmpty(orderId)) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SLS_ORDERNO_NULL.getCode(),
					ExceptionCodeDes.SLS_ORDERNO_NULL.getDescription());
		}

		MaxshuRespInfo respInfo = null;
		String address = PropertiesUtil.getValue(
				"maxshu.interface.query.order.address", filename);
		String md5key = PropertiesUtil.getValue("maxshu.md5.key", filename);
		String merchantId = PropertiesUtil.getValue("maxshu.merchant.id",
				filename);
		HttpClient httpClient = new HttpClient();
		String data = merchantId + orderId + md5key;
		String sign = UtilMD5Encryption.createMD5Encryption(data);
		Map<String, String> map = new HashMap<String, String>();
		map.put("MerchantID", merchantId);
		map.put("MerchantOrderID", orderId);
		map.put("Sign", sign);
		try {
			log.info("请求ID：" + head.getRequestId() + "--发送到数网订单查询的请求参数："
					+ address + map);
			String xmlStr = httpClient.doPost(address, map);
			log.info("请求ID：" + head.getRequestId() + "--数网返回的请求结果：" + xmlStr);
			if (StringUtils.isNotEmpty(xmlStr)) {
				respInfo = ParseMaxshuRespInfo.getBalanceInfo(xmlStr);
			}
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "--数网订单查询请求异常！", e);
		}
		return respInfo;

	}
	/**
	 * 
	 * */
	@Override
	public void updateOrderStatus(String body, Head head) {
		MaxshuRespInfo asyncInfo = gson.fromJson(body, MaxshuRespInfo.class);
		// 成功处理时间
		String orderSuccessTime = ServerDateAndTime.getNowDateTime().trim();
		String orderSuccessTime2 = ServerDateAndTime.getNowDateTimeOfFormat()
				.trim();
		boolean flag = this.checkData(asyncInfo);
		if (flag) {
			// 主动通知下游用户
			String userhandleResult = sendNotifyToDownUserMsg(asyncInfo,
					orderSuccessTime, head);
			updateGoodsOrder(head, asyncInfo, orderSuccessTime2,
					userhandleResult);
		}
	}

	@Override
	public void save(String body, Head head) {
		MaxshuProduct wp = gson.fromJson(body, MaxshuProduct.class);
		this.validate(wp);
		if (StringUtils.isEmpty(wp.getProductId())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.PRODCODE_EMPTY.getCode(),
					ExceptionCodeDes.PRODCODE_EMPTY.getDescription());
		}
		String productId = wp.getProductId();
		wp.setId(UUID.randomUUID().toString());
		wp.setInsertTime(ServerDateAndTime.getNowDateTimeOfFormat());
		MaxshuProduct woPro = maxshuDAO.queryByProId(productId);
		if (woPro == null) {
			wp.setIsAudit("0");
			maxshuDAO.insertProduct(wp);
		} else {
			wp.setId(woPro.getId());
			wp.setModifyTime(ServerDateAndTime.getNowDateTimeOfFormat());
			maxshuDAO.update(wp);
		}

	}

	/**
	 * 更新订单状态
	 * 
	 * @param head
	 * @param asyncInfo
	 * @param orderSuccessTime
	 * @param userhandleResult
	 */
	private void updateGoodsOrder(Head head, MaxshuRespInfo asyncInfo,
			String orderSuccessTime, String userhandleResult) {

		// sls订单编号
		String orderNo = asyncInfo.getOrderId();
		// SUP平台订单号
		String supOrderNo = asyncInfo.getMaxshuOrderId();
		// 订单交易状态
		String statusCode = asyncInfo.getState();
		String stateInfo = asyncInfo.getStateInfo();

		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setOrderId(orderNo);
		goodsOrderInfo.setSupOrderId(supOrderNo);

		String status = "1";
		if ("101".equals(statusCode)) { // 成功
			status = "1";
		} else { // 失败
			status = "0";
			// 退款操作
			DeductionRefundInfo dedInfo = null;
			dedInfo = DeductionRefund.refundWhenAsynCallBackFailed(orderNo,
					goodsOrderDAO, head);
			String paymentStatus = "";
			if (dedInfo != null) {
				paymentStatus = dedInfo.getPaymentStatus();
			}
			if ("1".equals(paymentStatus)) { // 成功
				goodsOrderInfo.setIsPay("3"); // 退款成功
				// 退款成功，通知下游用户
				DeductionRefund.noticeUserRefundMsg(orderNo, dedInfo,
						goodsOrderDAO, downstreamUserDAO, null);

			} else if ("2".equals(paymentStatus)) {
				GoodsOrderInfo orderInfo = goodsOrderDAO
						.queryByOrderId(orderNo);
				if (orderInfo != null) {
					String isPayValue = orderInfo.getIsPay(); // 支付状态值
					if ("1".equals(isPayValue)) {
						goodsOrderInfo.setIsPay("2"); // 退款失败
					}
				}
			}
		}
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setStatusRemark(stateInfo);
		goodsOrderInfo.setSupOrderSuccessTime(orderSuccessTime);
		goodsOrderInfo.setUserhandleResult(userhandleResult);
		goodsOrderInfo.setSynOrAsy("1"); // 异步推送
		// 数据更新
		try {
			baseService.updateOrderInfo(goodsOrderInfo, head);
//			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error("数网异步推送更新订单异常", e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

	}

	/**
	 * 通知最终订单状态给下游用户
	 * 
	 * @param asyncInfo
	 * @param orderSuccessTime
	 * @param head
	 * @return
	 */
	private String sendNotifyToDownUserMsg(MaxshuRespInfo asyncInfo,
			String orderSuccessTime, Head head) {
		String handleResult = "FAILED";
		String orderId = asyncInfo.getOrderId();
		GoodsOrderInfo orderInfo = this.goodsOrderDAO.queryByOrderId(orderId);
		String notifyUrl = "";
		// 下游用户编号
		String contractId = null;
		if (orderInfo != null) {
			notifyUrl = orderInfo.getNotifyUrl();
			contractId = orderInfo.getContractId();

			String secretKey = null; // 下游用户密钥
			DownstreamUserInfo downstreamUserInfo = downstreamUserDAO
					.queryUserByUserNO(contractId);
			if (downstreamUserInfo != null) {
				secretKey = downstreamUserInfo.getSecretKey();
			}
			String httpUrl = notifyUrl
					+ "?"
					+ this.assembleParameter(asyncInfo, orderInfo, secretKey,
							orderSuccessTime);

			HttpClient httpClient = new HttpClient();
			// 供应商返回消息编码方式
			String supplyEncode = "UTF-8";
			// 给下游发消息
			String xmlStr = "";
			try {
				log.info("请求ID：" + head.getRequestId() + "，异步回调给下游用户的url："
						+ httpUrl);
				xmlStr = httpClient.doGet(httpUrl, supplyEncode);
				log.info("请求ID：" + head.getRequestId() + "，下游用户的返回结果：" + xmlStr);
			} catch (Exception e) {
				log.error("请求ID：" + head.getRequestId() + "，主动通知下游用户出现异常！", e);
			}
			if (xmlStr != null && !("".equals(xmlStr))) {
				SLSHttpInterfaceInfo slsInfo = null;
				slsInfo = OrderStatusSendParse.readUserSendMsg(xmlStr);
				if (slsInfo != null) {
					handleResult = slsInfo.getHandleResult();
				}
			}
		}
		return handleResult;
	}

	private String assembleParameter(MaxshuRespInfo asyncInfo,
			GoodsOrderInfo orderInfo, String secretKey, String orderSuccessTime) {
		// 下游用户订单号
		String ptOrderNo = orderInfo.getMerchantOrderId();
		// 手拉手订单号
		String supOrderNo = asyncInfo.getOrderId();
		// 充值后状态
		String orderState = asyncInfo.getState();
		String err_msg = asyncInfo.getStateInfo();

		StringBuilder strBui = new StringBuilder();
		strBui.append("ptOrderNo=");
		strBui.append(ptOrderNo);
		strBui.append("&");
		strBui.append("supOrderNo=");
		strBui.append(supOrderNo);
		strBui.append("&");
		strBui.append("status=");
		String status = null;
		if ("101".equals(orderState)) { // 成功
			status = "ORDER_SUCCESS";
			err_msg = ""; // ----------成功了为空
		} else { // 失败
			status = "ORDER_FAILED"; // ---------失败
		}
		strBui.append(status);
		strBui.append("&");

		if ("ORDER_SUCCESS".equals(status)) { // ---------订单成功，才传成功充值时间
			strBui.append("supOrderSuccessTime=");
			strBui.append(orderSuccessTime);
			strBui.append("&");
		} else { // ---------------------订单失败时，才传错误码
			strBui.append("failedReason=");
			String fr = "";
			if (StringUtils.isNotBlank(err_msg)) {
				try {
					fr = URLEncoder.encode(err_msg, "UTF-8");
				} catch (UnsupportedEncodingException e) {
					log.error("编码异常", e);
				}
			}
			strBui.append(fr);
			strBui.append("&");
		}

		strBui.append("sign=");
		String sign = createSign(ptOrderNo, supOrderNo, status,
				orderSuccessTime, err_msg, secretKey);
		strBui.append(sign);

		String result = strBui.toString().trim();
		return result;

	}

	private String createSign(String ptOrderNo, String supOrderNo,
			String status, String orderSuccessTime, String err_msg,
			String secretKey) {
		StringBuilder strBui = new StringBuilder();
		strBui.append(ptOrderNo);
		strBui.append(supOrderNo);
		strBui.append(status);
		if (orderSuccessTime != null && !("".equals(orderSuccessTime))) {
			strBui.append(orderSuccessTime);
		}
		if (err_msg != null && !("".equals(err_msg))) {
			strBui.append(err_msg);
		}
		strBui.append(secretKey);
		String data = strBui.toString().trim();
		String result = UtilMD5Encryption.createMD5Encryption(data);
		return result;
	}

	private boolean checkData(MaxshuRespInfo asyncInfo) {
		boolean flag = false;
		if (StringUtils.isEmpty(asyncInfo.getMaxshuOrderId())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getCode(),
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getDescription());
		} else if (StringUtils.isEmpty(asyncInfo.getOrderId())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SLS_ORDERNO_NULL.getCode(),
					ExceptionCodeDes.SLS_ORDERNO_NULL.getDescription());
		} else if (StringUtils.isEmpty(asyncInfo.getState())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.EN_LINK_RESULTCODE_EMPTY.getCode(),
					ExceptionCodeDes.EN_LINK_RESULTCODE_EMPTY.getDescription());
		} else {
			flag = true;
		}
		return flag;
	}

	@Override
	public void update(String body, Head head) {
		MaxshuProduct product = gson.fromJson(body, MaxshuProduct.class);
		this.validate(product);
		product.setIsAudit("0");
		product.setModifyTime(ServerDateAndTime.getNowDateTimeOfFormat());
		try {
			this.maxshuDAO.update(product);
		} catch (Exception e) {
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

	}

	@Override
	public MaxshuProduct querySupProductById(String body, Head head) {
		String id = gson.fromJson(body, String.class);
		this.validate(id);
		MaxshuProduct product = this.maxshuDAO.queryById(id);
		return product;
	}

	@Override
	public Pagination<MaxshuProduct> querySupProPagination(String body,
			Head head) {
		MaxshuProduct product = gson.fromJson(body, MaxshuProduct.class);
		Pagination<MaxshuProduct> page = this.maxshuDAO.queryPage(product);
		return page;
	}

	@Override
	public Pagination<MaxshuAccountType> querySupATPagination(String body,
			Head head) {
		MaxshuAccountType acc = gson.fromJson(body, MaxshuAccountType.class);
		Pagination<MaxshuAccountType> page = this.maxshuAccountDAO
				.queryPage(acc);
		return page;
	}

	@Override
	public Pagination<MaxshuRechargeType> querySupRTPagination(String body,
			Head head) {
		MaxshuRechargeType recharge = gson.fromJson(body,
				MaxshuRechargeType.class);
		Pagination<MaxshuRechargeType> page = this.maxshuRechargeDAO
				.queryPage(recharge);
		return page;
	}

	@Override
	public Pagination<MaxshuAreaServer> querySupASPagination(String body,
			Head head) {
		MaxshuAreaServer as = gson.fromJson(body, MaxshuAreaServer.class);
		Pagination<MaxshuAreaServer> page = this.maxshuAsDAO.queryPage(as);
		return page;
	}

	/**
	 * 校验是否为空
	 * 
	 * @param obj
	 */
	private void validate(Object obj) {
		if (obj == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.PARSE_REQUEST_ERROR.getCode(),
					ExceptionCodeDes.PARSE_REQUEST_ERROR.getDescription());
		}
	}
	
}
